
#include "stdafx.h"

//////////////////////////// recv ////////////////////////////
TEST(recvTest, recv_in_inout)
{
    SOCKET sock = INVALID_SOCKET;
    int len = 11;
    int flags = 0x2 | 0x8;
    
    Header header(GetCurrentThreadId(), "recv");
    recv_in_inout recvIN(sock, len, flags);
    recv_in_inout recvOUT;

    std::vector<char> buffer;
    Serialize(header, recvIN, buffer);
        
    Deserialize deserialize(buffer);
    deserialize(recvOUT);

    EXPECT_EQ(header.TID_, deserialize.get_header().TID_);
    EXPECT_EQ(header.func_name_, deserialize.get_header().func_name_);

    EXPECT_EQ(recvIN.s_, recvOUT.s_);
    EXPECT_EQ(recvIN.len_, recvOUT.len_);
    EXPECT_EQ(recvIN.flags_, recvOUT.flags_);
}

//TEST(recvTest, recv_in_inout_NULL_parameters)
//{
//    
//}

TEST(recvTest, recv_out_inout)
{
    SOCKET sock = INVALID_SOCKET;
    int ret = 11;
    char buf[100];
    
    std::fill(buf, buf+100, 'b');
    Header header(GetCurrentThreadId(), "recv");
    recv_out_inout recvIN(ret, buf, 100, 7);
    recv_out_inout recvOUT;

    std::vector<char> buffer;
    Serialize(header, recvIN, buffer);
        
    Deserialize deserialize(buffer);
    deserialize(recvOUT);

    EXPECT_EQ(header.TID_, deserialize.get_header().TID_);
    EXPECT_EQ(header.func_name_, deserialize.get_header().func_name_);

    EXPECT_EQ(recvIN.ret_, recvOUT.ret_);
    if (recvIN.buf_ && recvOUT.buf_)
    {
        int cmp = strncmp (recvIN.buf_, recvOUT.buf_, 100);
        EXPECT_TRUE(!cmp);
    }
    else {
        EXPECT_FALSE(recvIN.buf_);
        EXPECT_FALSE(recvOUT.buf_);
    }
    EXPECT_EQ(recvIN.wsa_last_error_, recvOUT.wsa_last_error_);
}

TEST(recvTest, recv_out_inout_NULL_parameters)
{
    SOCKET sock = INVALID_SOCKET;
    int ret = 11;
    
    Header header(GetCurrentThreadId(), "recv");
    recv_out_inout recvIN(ret, NULL, 0, 7);
    recv_out_inout recvOUT;

    std::vector<char> buffer;
    Serialize(header, recvIN, buffer);
        
    Deserialize deserialize(buffer);
    deserialize(recvOUT);

    EXPECT_EQ(header.TID_, deserialize.get_header().TID_);
    EXPECT_EQ(header.func_name_, deserialize.get_header().func_name_);

    EXPECT_EQ(recvIN.ret_, recvOUT.ret_);
    if (recvIN.buf_ && recvOUT.buf_)
    {
        int cmp = strncmp (recvIN.buf_, recvOUT.buf_, 100);
        EXPECT_TRUE(!cmp);
    }
    else {
        EXPECT_FALSE(recvIN.buf_);
        EXPECT_FALSE(recvOUT.buf_);
    }
    EXPECT_EQ(recvIN.wsa_last_error_, recvOUT.wsa_last_error_);
}

//////////////////////////// recvfrom ////////////////////////////
TEST(recvfromTest, recvfrom_in_inout)
{
    SOCKET sock = INVALID_SOCKET;
    int len = 11;
    int flags = 0x2 | 0x8;
    int fromlen = 10;
    
    Header header(GetCurrentThreadId(), "recvfrom");
    recvfrom_in_inout recvfromIN(sock, len, flags, &fromlen);
    recvfrom_in_inout recvfromOUT;

    std::vector<char> buffer;
    Serialize(header, recvfromIN, buffer);
        
    Deserialize deserialize(buffer);
    deserialize(recvfromOUT);

    EXPECT_EQ(header.TID_, deserialize.get_header().TID_);
    EXPECT_EQ(header.func_name_, deserialize.get_header().func_name_);

    EXPECT_EQ(recvfromIN.s_, recvfromOUT.s_);
    EXPECT_EQ(recvfromIN.len_, recvfromOUT.len_);
    EXPECT_EQ(recvfromIN.flags_, recvfromOUT.flags_);
}

TEST(recvfromTest, recvfrom_in_inout_NULL_parameters)
{
    SOCKET sock = INVALID_SOCKET;
    int len = 11;
    int flags = 0x2 | 0x8;
    
    Header header(GetCurrentThreadId(), "recvfrom");
    recvfrom_in_inout recvfromIN(sock, len, flags, NULL);
    recvfrom_in_inout recvfromOUT;

    std::vector<char> buffer;
    Serialize(header, recvfromIN, buffer);
        
    Deserialize deserialize(buffer);
    deserialize(recvfromOUT);

    EXPECT_EQ(header.TID_, deserialize.get_header().TID_);
    EXPECT_EQ(header.func_name_, deserialize.get_header().func_name_);

    EXPECT_EQ(recvfromIN.s_, recvfromOUT.s_);
    EXPECT_EQ(recvfromIN.len_, recvfromOUT.len_);
    EXPECT_EQ(recvfromIN.flags_, recvfromOUT.flags_);
}

TEST(recvfromTest, recvfrom_out_inout)
{
    SOCKET sock = INVALID_SOCKET;
    int ret = 11;
    char buf[100];

    sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    addr.sin_port = htons(27015);

    int len = sizeof(addr);
    
    std::fill(buf, buf+100, 'b');
    Header header(GetCurrentThreadId(), "recvfrom");
    recvfrom_out_inout recvfromIN(ret, buf, 100, (SOCKADDR*)&addr, &len, 7);
    recvfrom_out_inout recvfromOUT;

    std::vector<char> buffer;
    Serialize(header, recvfromIN, buffer);
        
    Deserialize deserialize(buffer);
    deserialize(recvfromOUT);

    EXPECT_EQ(header.TID_, deserialize.get_header().TID_);
    EXPECT_EQ(header.func_name_, deserialize.get_header().func_name_);

    EXPECT_EQ(recvfromIN.ret_, recvfromOUT.ret_);
    if (recvfromIN.buf_ && recvfromOUT.buf_)
    {
        int cmp = strncmp (recvfromIN.buf_, recvfromOUT.buf_, 100);
        EXPECT_TRUE(!cmp);
    }
    else {
        EXPECT_FALSE(recvfromIN.buf_);
        EXPECT_FALSE(recvfromOUT.buf_);
    }
    if (recvfromIN.from_ && recvfromOUT.from_)
    {
        EXPECT_EQ (recvfromIN.from_->sa_family, recvfromOUT.from_->sa_family);
        int cmp = strncmp (recvfromIN.from_->sa_data, recvfromOUT.from_->sa_data, 14);
        EXPECT_TRUE(!cmp);
    }
    else {
        EXPECT_FALSE(recvfromIN.from_);
        EXPECT_FALSE(recvfromOUT.from_);
    }
    if (recvfromIN.fromlen_ && recvfromOUT.fromlen_)
    {
        EXPECT_EQ(*recvfromIN.fromlen_, *recvfromOUT.fromlen_);
    }
    else {
        EXPECT_FALSE(recvfromIN.fromlen_);
        EXPECT_FALSE(recvfromOUT.fromlen_);
    }
    EXPECT_EQ(recvfromIN.wsa_last_error_, recvfromOUT.wsa_last_error_);
}

TEST(recvfromTest, recvfrom_out_inout_NULL_parameters)
{
    SOCKET sock = INVALID_SOCKET;
    int ret = 11;
    char buf[100];

    sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    addr.sin_port = htons(27015);

    int len = sizeof(addr);
    
    std::fill(buf, buf+100, 'b');
    Header header(GetCurrentThreadId(), "recvfrom");
    //recvfrom_out_inout recvfromIN(ret, NULL, 0, (SOCKADDR*)&addr, &len, 7);
    //recvfrom_out_inout recvfromIN(ret, NULL, 0, NULL, &len, 7);
    //recvfrom_out_inout recvfromIN(ret, NULL, 0, (SOCKADDR*)&addr, NULL, 7);
    recvfrom_out_inout recvfromIN(ret, NULL, 0, NULL, NULL, 7);
    recvfrom_out_inout recvfromOUT;

    std::vector<char> buffer;
    Serialize(header, recvfromIN, buffer);
        
    Deserialize deserialize(buffer);
    deserialize(recvfromOUT);

    EXPECT_EQ(header.TID_, deserialize.get_header().TID_);
    EXPECT_EQ(header.func_name_, deserialize.get_header().func_name_);

    EXPECT_EQ(recvfromIN.ret_, recvfromOUT.ret_);
    if (recvfromIN.buf_ && recvfromOUT.buf_)
    {
        int cmp = strncmp (recvfromIN.buf_, recvfromOUT.buf_, 100);
        EXPECT_TRUE(!cmp);
    }
    else {
        EXPECT_FALSE(recvfromIN.buf_);
        EXPECT_FALSE(recvfromOUT.buf_);
    }
    if (recvfromIN.from_ && recvfromOUT.from_)
    {
        EXPECT_EQ (recvfromIN.from_->sa_family, recvfromOUT.from_->sa_family);
        int cmp = strncmp (recvfromIN.from_->sa_data, recvfromOUT.from_->sa_data, 14);
        EXPECT_TRUE(!cmp);
    }
    else {
        EXPECT_FALSE(recvfromIN.from_);
        EXPECT_FALSE(recvfromOUT.from_);
    }
    if (recvfromIN.fromlen_ && recvfromOUT.fromlen_)
    {
        EXPECT_EQ(*recvfromIN.fromlen_, *recvfromOUT.fromlen_);
    }
    else {
        EXPECT_FALSE(recvfromIN.fromlen_);
        EXPECT_FALSE(recvfromOUT.fromlen_);
    }
    EXPECT_EQ(recvfromIN.wsa_last_error_, recvfromOUT.wsa_last_error_);
}
